package com.bjsxt;
/**线程同步：处理多线程问题时，多个线程访问同一个对象，并且某些线程还想修改对象。
 * 这时候，我们就需要用到“线程同步”，线程同步其实就是一种等待机制，多个需要
 * 同时访问此对象的线程进入这个对象的等待池形成队列，等待前面的线程使用完毕后，下一
 * 个线程再使用*/
public class SynchronizedTest00 {
    /*实现线程同步：由于同一进程的多个线程共享同一块存储空间，在带来方便的同时，也带来了访问冲突的
    * 问题。java 语言提供了专门机制以解决这种冲突，有效避免了同一个数据对象被多个线程
    * 同时访问造成的这种问题。这套机制就是synchronized 关键字*/
    //语法结构：
    /*  synchronized(锁对象){ 同步代码 }
    * synchronized 关键字使用时需要考虑的问题：
    *1，需要对那部分的代码在执行时具有线程互斥的能力（线程互斥：并行变串行）
    * 2，需要对哪些线程中的代码具有互斥能力（通过synchronized 锁对象来决定），
    * 它包括两种用法：synchronized 方法和synchronized 块
    * （有相同锁的代码具有互斥的能力）*/
    //互斥的能力:只有在相同对象下的方法，在不同线程当中运行
    /*synchronized 方法
    * 通过在方法声明中加入 synchronized 关键字来声明，语法如下：
    * public synchronized void accessVal(int newVal);
    *   synchronized 在方法声明时使用：放在范围操作符（public）之后，返回类型声明（void）之前
    * 这时同一个对象下synchronized 方法在多线程中执行时，该方法是同步的，即一次
    * 只能有一个线程进入该方法，其他线程要想在此时调用该方法，只能排队等候，当前线程就是在synchronized 方法内部的线程执行完
    * 该方法后，别的线程才能进入。*/
    /*synchronized 块
    * synchronized 方法的缺点：若将一个在的方法声明为synchronized 将会
    * 大大影响效率。
    * synchronized 块可以让我们精确地控制到具体的“成员变量”，繽小同步范围，提高效率
    * （“局部变量”是不存在线程不安全的问题）*/

//使用this作为线程对象锁    在不同线程中，相同对象中的synchronized会互斥
// 语法结构：
    /*  synchronized(锁对象){ 同步代码 }
    或  public synchronized void accessVal(int newVal){}
    * ():小括号是锁定哪些线程的块要作同步处理  在多线程当中只有持有相同的锁才会同0步处理
    * {}:大括号是要同步的代码
    synchronized 放在pubic 和void 之间*/

//使用字符串作为线程对象锁
/*所有线程在执行synchronized时都会同步
*  synchronized("字符串"){ 同步代码 }*/

//使用Class作为线程对象锁
// 在不同线程中，拥有相同Class对象中的synchronized 会互斥
/*    synchronized(xx.class){ 同步代码 }
或 加到静态方法上：synchronized public static void accessVal(){}
静态方法上的对象锁是以静态方法上的类为对象锁
 */

//使用自定义对象作为线程对象锁
//在不同线程中，拥有相同自定义对象中的synchronized 会互斥
// 语法结构：synchronized(自定义对象){ 同步代码 }

/*死锁的概念：多个线程各自占有一些共享资源，并且互相等待其他线程占有的资源才
* 能进行，而导致两个或者多个线程都在等待对方释放资源，都停止执行的情形。
*   因此，某一个同步需要同时拥有“两个以上对象的锁”时，就可能会发生“死锁”
* 的问题，比如，“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。
* 那么，实际运行时，“小红的化状”拥有“镜子对象”，“大红的化状线程”拥有了“口红对象”
* 都在互相等待对方释放资源，才能化状。这样，两个线程就形成了互相等待，无法继续运行的“死锁状态”*/
}
